#include "../Base/stdafx.h"
#include "TreeNode.h"
#include "../Base/DXDevice.h"
#include "../Base/GameEngine.h"
#include "../PhysX/PhysX.h"

TreeNode::TreeNode():m_DefScale(D3DXVECTOR3(1,1,1)), 
		m_DefTran(D3DXVECTOR3(0,0,0)), m_DefRot(D3DXVECTOR3(0,0,0)), 
		m_Scale(D3DXVECTOR3(1,1,1)), m_Tran(D3DXVECTOR3(0,0,0)), m_Changed(true),
		m_Rot(D3DXVECTOR3(0,0,0)), m_Pivot(D3DXVECTOR3(0,0,0)), m_Parent(0), m_Actor(0)
{

}

TreeNode::~TreeNode()
{
}

void TreeNode::Rotate(const D3DXVECTOR3& rot)
{
	//m_Rot += rot;
	D3DXMATRIX rotation;
	D3DXMatrixRotationYawPitchRoll(&rotation, rot.y, rot.x, rot.z);
	m_World *= rotation;
}

void TreeNode::Translate(const D3DXVECTOR3& tran)
{
	//m_Tran += tran;
	D3DXMATRIX translation;
	D3DXMatrixTranslation(&translation, tran.x, tran.y, tran.z);
	m_World *= translation;
}

void TreeNode::Scale(const D3DXVECTOR3& scale)
{
	//m_Scale += scale;
	D3DXMATRIX scaling;
	D3DXMatrixScaling(&scaling, scale.x, scale.y, scale.z);
	m_World *= scaling;
}

void TreeNode::ResetWorldMatrix()
{
	D3DXMatrixIdentity(&m_World);
}

D3DXMATRIX TreeNode::GetWorldMatrix()
{
	GetTotalTranspose();
	return m_World;
}

const tstring& TreeNode::GetName() const
{
	return m_MeshDesc.name;
}

void TreeNode::GetTotalTranspose()
{
	ResetWorldMatrix(); 
	if(m_MeshDesc.state == MeshDesc::PhysxStatic || m_Actor == 0 || m_Changed)
	{
		if(m_DefScale != D3DXVECTOR3(1,1,1))
			Scale(m_DefScale);
		Scale(m_Scale);

		D3DXVECTOR3 pivot = m_Pivot;
		pivot.x *= m_DefScale.x;
		pivot.y *= m_DefScale.y;
		pivot.z *= m_DefScale.z;
		if(pivot != D3DXVECTOR3(0,0,0))
			Translate(pivot);

		if(m_DefRot != D3DXVECTOR3(0,0,0))
			Rotate(m_DefRot);
		Rotate(m_Rot);

		if(m_DefTran != D3DXVECTOR3(0,0,0))
			Translate(m_DefTran);
		Translate(m_Tran);

		if(m_Actor)
		{
			NxMat34 nxRot;
			nxRot.setColumnMajor44(m_World);
			m_Actor->setGlobalPose(nxRot);
		}

		m_Changed = false;

	}else{
		NxMat34 pos = m_Actor->getGlobalPose();
		pos.getColumnMajor44(m_World);
	}

	if(m_Parent != 0)
	{
		m_Parent->GetTotalTranspose();
		m_World *= m_Parent->GetWorldMatrix();
	}
}

void TreeNode::AddParent(TreeNode* parent)
{
	m_Parent = parent;
}

void TreeNode::InLib()
{
	m_MeshDesc.inLib = true;
}

bool TreeNode::IsInLib() const
{
	return m_MeshDesc.inLib;
}

void TreeNode::SetScale(const D3DXVECTOR3& scale)
{
	m_Scale = scale;
}	
void TreeNode::SetRotation(const D3DXVECTOR3& rot)
{
	m_Rot = rot;
	m_Changed = true;
}

void TreeNode::SetTranslate(const D3DXVECTOR3& tran)
{
	m_Tran = tran;
	m_Changed = true;
}

const D3DXVECTOR3& TreeNode::GetScale() const
{
	return m_Scale;
}

const D3DXVECTOR3& TreeNode::GetRotation() const
{
	return m_Rot;
}

const D3DXVECTOR3& TreeNode::GetTranslation() const
{
	return m_Tran;
}

void TreeNode::AddScale( const D3DXVECTOR3& scale )
{
	m_Scale += scale;
	m_Changed = true;
}

void TreeNode::AddRotation( const D3DXVECTOR3& rot )
{
	m_Rot += rot;
	m_Changed = true;
}

void TreeNode::AddTranslate( const D3DXVECTOR3& tran )
{
	m_Tran += tran;
	m_Changed = true;
}

void TreeNode::AddForce( D3DXVECTOR3 force )
{
	if(m_Actor != 0)
		m_Actor->addForce(NxVec3(force.x, force.y, force.z), NX_IMPULSE);
}

bool TreeNode::CastShadow() const
{
	return m_MeshDesc.castShadow;
}

void TreeNode::SetDistance( float dist )
{
	m_Distance = dist;
}

float TreeNode::GetDistance() const
{
	return m_Distance;
}

MeshDesc& TreeNode::GetDesc()
{
	return m_MeshDesc;
}

void TreeNode::SetPivot( const D3DXVECTOR3& pivot )
{
	m_DefTran = pivot;
}